package service

import (
	"azfirewall-gateway/data"
	"azfirewall-gateway/models"
	"azfirewall-gateway/utils"
	valid "github.com/asaskevich/govalidator"
	"github.com/syndtr/goleveldb/leveldb"
	"github.com/syndtr/goleveldb/leveldb/util"
	"github.com/vence722/convert"
	"net/http"
	"time"
)

func SiteAM(r *http.Request, w http.ResponseWriter) {

	var siteStrut = new(models.Site)
	siteParams := &models.SiteAMParams{
		Domain:          r.URL.Query().Get("domain"),
		RedirectHttps:   r.URL.Query().Get("redirect_https"),
		HSTS:            r.URL.Query().Get("hsts"),
		WAF:             r.URL.Query().Get("waf"),
		SourcePort:      r.URL.Query().Get("source_port"),
		SourceIP:        r.URL.Query().Get("source_ip"),
		IntervalSeconds: r.URL.Query().Get("interval_seconds"),
		MaxCount:        r.URL.Query().Get("max_count"),
		BlockSeconds:    r.URL.Query().Get("block_seconds"),
		CCAction:        r.URL.Query().Get("cc_action"),
	}
	valid.SetFieldsRequiredByDefault(true)
	if valid.IsDNSName(siteParams.Domain) {
		if valid.IsNotNull(siteParams.RedirectHttps) {
			if valid.IsNotNull(siteParams.HSTS) {
				if valid.IsNotNull(siteParams.WAF) {
					if valid.IsPort(siteParams.SourcePort) {
						if valid.IsIP(siteParams.SourceIP) {
							if valid.IsNumeric(siteParams.IntervalSeconds) && valid.IsNumeric(siteParams.MaxCount) && valid.IsNumeric(siteParams.BlockSeconds) && valid.IsNumeric(siteParams.CCAction) {
								siteStrut.DomainName = siteParams.Domain
								siteStrut.InternalProtocol = "http"
								if siteParams.HSTS == "true" {
									siteStrut.HSTSEnabled = true
								} else {
									siteStrut.HSTSEnabled = false
								}
								if siteParams.RedirectHttps == "true" {
									siteStrut.RedirectHttps = true
								} else {
									siteStrut.HSTSEnabled = false
								}
								if siteParams.WAF == "true" {
									siteStrut.WAFEnabled = true
								} else {
									siteStrut.WAFEnabled = false
								}
								siteStrut.SourceSite = &models.SourceSite{IP: siteParams.SourceIP, Port: siteParams.SourcePort}
								siteStrut.SiteCCPolicy = &models.CCPolicy{
									IntervalSeconds: time.Duration(convert.Str2Float64(siteParams.IntervalSeconds)),
									MaxCount:        convert.Str2Int64(siteParams.MaxCount),
									BlockSeconds:    time.Duration(convert.Str2Float64(siteParams.BlockSeconds)),
									Action:          models.PolicyAction(convert.Str2Int64(siteParams.CCAction)),
								}
								err := data.DBP.SiteDb.Put([]byte("SITE-"+siteStrut.DomainName), data.SiteStructToJsonByteArr(*siteStrut), nil)
								if err != nil {
									utils.MainLog.Error("新增站点写库时发生错误：", err)
									utils.ProcessResponse(w, models.SystemError, "新增站点写库时发生错误：", nil)
									return
								}
								utils.ProcessResponse(w, models.Success, "成功新增或更改站点信息", nil)
								return
							} else {
								utils.ProcessResponse(w, models.InvalidParam, "CC防御策略配置错误，请检查！", nil)
								return
							}
						} else {
							utils.ProcessResponse(w, models.InvalidParam, "原站IP格式错误，请检查！", nil)
							return
						}
					} else {
						utils.ProcessResponse(w, models.InvalidParam, "原站端口格式错误，请检查！", nil)
						return
					}
				} else {
					utils.ProcessResponse(w, models.InvalidParam, "WAF开关格式错误，请检查！", nil)
					return
				}
			} else {
				utils.ProcessResponse(w, models.InvalidParam, "HSTS配置格式错误，请检查！", nil)
				return
			}
		} else {
			utils.ProcessResponse(w, models.InvalidParam, "重定向HTTPS配置格式错误，请检查！", nil)
			return
		}
	} else {
		utils.ProcessResponse(w, models.InvalidParam, "域名格式错误，请检查！", nil)
		return
	}
}
func SitesQuery(r *http.Request, w http.ResponseWriter) {
	params := r.URL.Query()
	if len(params["mode"]) > 0 {
		if params["mode"][0] == "all" {
			var sites []*models.Site
			iter := data.DBP.SiteDb.NewIterator(util.BytesPrefix([]byte("SITE-")), nil)
			for iter.Next() {
				each := data.JsonByteArrToSiteStruct(iter.Value())
				sites = append(sites, each)
			}
			iter.Release()
			err := iter.Error()
			if err != nil {
				utils.MainLog.Error("查询全部站点信息过程中发生错误：", err)
				utils.ProcessResponse(w, models.SystemError, "查询全部站点信息过程中发生错误", nil)
				return
			}
			utils.ProcessResponse(w, models.Success, "数据查询成功！", sites)
			return
		} else if params["mode"][0] == "domain" {
			if len(params["domain"]) > 0 {
				searchSpecificSite, err := data.DBP.SiteDb.Get([]byte("SITE-"+params["domain"][0]), nil)
				if err != nil {
					if err == leveldb.ErrNotFound {
						utils.ProcessResponse(w, models.ResourceNotFound, "站点数据不存在", nil)
						return
					}
					utils.MainLog.Error("查询指定站点信息过程中发生错误：", err)
					utils.ProcessResponse(w, models.SystemError, "查询指定站点信息过程中发生错误", nil)
					return
				}
				site := data.JsonByteArrToSiteStruct(searchSpecificSite)
				utils.ProcessResponse(w, models.Success, "数据查询成功！", site)
				return
			} else {
				utils.ProcessResponse(w, models.InvalidParam, "请求参数验证错误：必须提供域名信息", nil)
				return
			}
		} else {
			utils.ProcessResponse(w, models.InvalidParam, "请求参数验证错误：无效的mode指令", nil)
			return
		}
	} else {
		utils.ProcessResponse(w, models.InvalidParam, "请求参数验证错误，请检查参数是否完整正确", nil)
		return
	}
}
func SiteDelete(r *http.Request, w http.ResponseWriter) {
	params := r.URL.Query()
	if len(params["domain"]) > 0 {
		err := data.DBP.SiteDb.Delete([]byte("SITE-"+params["domain"][0]), nil)
		if err != nil {
			utils.MainLog.Error("删除站点数据时发生错误：", err)
			utils.ProcessResponse(w, models.SystemError, "删除站点数据时发生错误", nil)
			return
		}
		utils.ProcessResponse(w, models.Success, "成功删除指定数据", nil)
	} else {
		utils.ProcessResponse(w, models.InvalidParam, "请求参数验证错误：domain参数为必须项", nil)
		return
	}
}
func CertAdd(r *http.Request, w http.ResponseWriter) {
}
func CertDelete(r *http.Request, w http.ResponseWriter) {

}
